#include "nativ_ContourGenerator.h"
#include <sgCore.h>

JNIEXPORT jobjectArray JNICALL Java_nativ_ContourGenerator_generateContour(JNIEnv *env, jobject obj, jobjectArray pts, jdouble dist)
{	
	sgInitKernel();

	jclass pntClass = env->FindClass("java/awt/geom/Point2D$Double");
	
	jmethodID getX = env->GetMethodID(pntClass, "getX", "()D");
	jmethodID getY = env->GetMethodID(pntClass, "getY", "()D");
	jmethodID con = env->GetMethodID(pntClass, "<init>", "(DD)V");

	jsize numPts = env->GetArrayLength(pts);

	sgCObject** lines = new sgCObject*[numPts];

	for (int i = 0; i < numPts; i++)
	{		
		jobject pt1 = env->GetObjectArrayElement(pts, i % numPts);
		jobject pt2 = env->GetObjectArrayElement(pts, (i+1) % numPts);

		env->CallDoubleMethod(pt1, getX);
		env->CallDoubleMethod(pt1, getY);

		lines[i] = sgCreateLine(
			env->CallDoubleMethod(pt1, getX),
			env->CallDoubleMethod(pt1, getY),
			0.0,
			env->CallDoubleMethod(pt2, getX),
			env->CallDoubleMethod(pt2, getY),
			0.0
			);

		if (sgGetLastError() != SG_ER_SUCCESS)
			env->ThrowNew(env->FindClass("java/lang/Exception"), "CreateLine failed");
	}

	sgCContour *contour = sgCContour::CreateContour(lines, numPts);
	if (sgGetLastError() != SG_ER_SUCCESS)
			env->ThrowNew(env->FindClass("java/lang/Exception"), "CreateContour failed");

	sgCContour *inset = contour->GetEquidistantContour(dist, dist, true);
	if (sgGetLastError() != SG_ER_SUCCESS)
			env->ThrowNew(env->FindClass("java/lang/Exception"), "CreateInset failed");

	//Convert contour back into points
	int numParts = inset->GetChildrenList()->GetCount();
	sgCObject **parts = new sgCObject*[numParts];
	inset->BreakContour(parts);	

	jobjectArray jInset = env->NewObjectArray(numParts, pntClass, env->GetObjectArrayElement(pts, 0));

	for (int i = 0; i < numParts; i++)
	{
		jobject pnt = env->NewObject(pntClass, con, reinterpret_cast<sgCLine*>(parts[i])->GetGeometry()->p1.x, reinterpret_cast<sgCLine*>(parts[i])->GetGeometry()->p1.y);
		env->SetObjectArrayElement(jInset, i, pnt);
	}

	for (int i = 0; i < numPts; i++)
		sgCObject::DeleteObject(lines[i]);

	for (int i = 0; i < numParts; i++)
		sgCObject::DeleteObject(parts[i]);

	sgCObject::DeleteObject(contour);
	sgCObject::DeleteObject(inset);

	sgFreeKernel();

	return jInset;
}